package com.wzdigit.wms.wms.controller.TransferWareHouse;

import com.wzdigit.framework.exception.RestStatusException;
import com.wzdigit.framework.model.response.ErrorEntity;
import com.wzdigit.wms.basic.util.HttpSessionUtil;
import com.wzdigit.wms.common.utils.ValidatorUtil;
import com.wzdigit.wms.basic.client.Pager;
import com.wzdigit.wms.basic.client.PagerInfo;
import com.wzdigit.wms.basic.client.request.transfer.*;
import com.wzdigit.wms.basic.client.response.Result;
import com.wzdigit.wms.basic.client.response.transfer.*;
import com.wzdigit.wms.wms.constant.WmsWareConstant;
import com.wzdigit.wms.wms.service.outbound.PicktaskService;
import com.wzdigit.wms.wms.service.transfer.GdnService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.List;

/**
 * <p>
 * 发货单-- 前端控制器
 * </p>
 *
 * @author
 * @since 2021-01-12
 */
@RestController
@Api(tags = "发货单")
@RequestMapping(value = WmsWareConstant.API_VERSION)
public class GdnController {

    public static final String REQUEST_MODEL = "/gdn";

    @Autowired
    private GdnService gdnService;

    @Autowired
	private PicktaskService picktaskService;

	/**
	 * 发货单列表
	 * @param dto
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 */
	@ApiOperation(value = "发货单列表",notes = "发货单列表")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @GetMapping(value = REQUEST_MODEL + "/searchGdnHeader")
    public PagerInfo<List<GdnHeaderListResponse>> searchGdnHeader(
    		SearchGdnHeaderRequest dto, Pager<?> pager,
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) {
        try {
            return gdnService.searchGdnHeader(dto, pager);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }
	
	/**
	 * 发货单明细列表
	 * @param dto
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 */
	@ApiOperation(value = "发货单明细列表",notes = "发货单列表")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @GetMapping(value = REQUEST_MODEL + "/searchGdnDtl")
    public PagerInfo<List<GdnDtlListResponse>> searchGdnDtl(
    		SearchGdnDtlRequest dto, Pager<?> pager,
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) {
        try {
            return gdnService.searchGdnDtl(dto, pager);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }
	
	/**
	 * 拣货进度详情
	 * @param gdnHeaderId
	 * @param pager
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 */
	@ApiOperation(value = "拣货进度详情",notes = "拣货进度详情")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @GetMapping(value = REQUEST_MODEL + "/searchPickTaskProgress")
	public <T> PagerInfo<List<PickTaskProgressResponse>> searchPickTaskProgress(
    		@ApiParam(value = "发货单表头ID", required = true) 
    		@RequestParam(required = true) Integer gdnHeaderId, 
    		Pager<T> pager, 
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) {
        try {
            return gdnService.searchPickTaskProgress(gdnHeaderId, pager);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }
	
	/**
	 * 发货单明细SN列表
	 * @param gdnDtlId
	 * @param pager
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 */
	@ApiOperation(value = "发货单明细SN列表",notes = "发货单明细SN列表")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @GetMapping(value = REQUEST_MODEL + "/searchGdnDtlGoods")
    public <T> PagerInfo<List<GdnDtlGoodsListResponse>> searchGdnDtlGoods(
    		@ApiParam(value = "发货单明细ID", required = true) 
    		@RequestParam(required = true) Integer gdnDtlId, 
    		Pager<T> pager, 
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) {
        try {
            return gdnService.searchGdnDtlGoods(gdnDtlId, pager);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }
	
	/**
	 * 排柜信息列表
	 * @param pager
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 */
	@ApiOperation(value = "排柜信息",notes = "排柜信息")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @GetMapping(value = REQUEST_MODEL + "/searchCtnrLoading")
    public <T> PagerInfo<List<CtnrLoadingResponse>> searchCtnrLoading(
    		@ApiParam(value = "发货单表头ID", required = true) 
    		@RequestParam(required = true) Integer gdnHeaderId, 
    		Pager<T> pager, 
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) {
        try {
            return gdnService.searchCtnrLoading(gdnHeaderId, pager);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }
	
	/**
	 * 增加货柜
	 * @param dto
	 * @param bindingResult
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 */
	@ApiOperation(value = "增加货柜",notes = "增加货柜")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @PostMapping(value = REQUEST_MODEL + "/addCtnrLoading")
    public Result<?> addCtnrLoading(
    		@RequestBody @Valid AddCtnrLoadingRequest dto, 
    		BindingResult bindingResult, 
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) {
        try {
        	ValidatorUtil.validator(bindingResult);
            return gdnService.addCtnrLoading(dto, servletRequest);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }
	
	/**
	 * 排柜
	 * @param dto
	 * @param bindingResult
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 */
	@ApiOperation(value = "排柜",notes = "排柜")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @PostMapping(value = REQUEST_MODEL + "/rowCtnrLoading")
    public Result<?> rowCtnrLoading(
    		@RequestBody @Valid RowCtnrLoadingRequest dto, 
    		BindingResult bindingResult, 
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) {
        try {
        	ValidatorUtil.validator(bindingResult);
            return gdnService.rowCtnrLoading(dto, servletRequest);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }
	
	/**
	 * 编辑货柜
	 * @param dto
	 * @param bindingResult
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 */
	@ApiOperation(value = "编辑货柜",notes = "编辑货柜")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @PostMapping(value = REQUEST_MODEL + "/updateCtnrLoading")
    public Result<?> updateCtnrLoading(
    		@RequestBody @Valid UpdateCtnrLoadingRequest dto, 
    		BindingResult bindingResult, 
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) {
        try {
        	ValidatorUtil.validator(bindingResult);
            return gdnService.updateCtnrLoading(dto, servletRequest);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }
	
	/**
	 * 获取可用库存
	 * @param gdnDtlId
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 */
	@ApiOperation(value = "获取可用库存",notes = "获取可用库存")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @GetMapping(value = REQUEST_MODEL + "/getAvailableInvZone")
    public List<AvailableInvZoneGroupWhsResponse> getAvailableInvZone(
    		@ApiParam(value = "发货单明细ID", required = true) 
    		@RequestParam(required = true) Long gdnDtlId,
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) {
        try {
            return gdnService.getAvailableInvZone(gdnDtlId, servletRequest);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }
	
	/**
	 * 确认分配库存
	 * @param dto
	 * @param bindingResult
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 * @throws Exception 
	 */
	@ApiOperation(value = "确认分配库存",notes = "确认分配库存")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @PostMapping(value = REQUEST_MODEL + "/confirmInvZone")
    public Result<?> confirmInvZone(
    		@RequestBody @Valid ConfirmInvZoneRequest dto, 
    		BindingResult bindingResult, 
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) throws Exception {
        try {
        	ValidatorUtil.validator(bindingResult);
            return gdnService.confirmInvZone(dto, servletRequest);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }
	
	/**
	 * 取消分配库存
	 * @param gdnDtlId
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 */
	@ApiOperation(value = "取消分配库存",notes = "取消分配库存")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @PutMapping(value = REQUEST_MODEL + "/cancelInvZone")
    public Result<?> cancelInvZone(
    		@ApiParam(value = "发货单明细ID", required = true) 
    		@RequestParam(required = true) Integer gdnDtlId,
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) {
        try {
            return gdnService.cancelInvZone(gdnDtlId, servletRequest);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }
	
	/**
	 * 获取原装柜信息
	 * @param gdnHeaderId
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 */
	@ApiOperation(value = "获取原装柜信息",notes = "获取原装柜信息")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @GetMapping(value = REQUEST_MODEL + "/searchCtnrLoadingPrint")
    public CtnrLoadingPrintResponse searchCtnrLoadingPrint(
    		@ApiParam(value = "发货单ID", required = true) 
    		@RequestParam(required = true) Integer gdnHeaderId, 
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) {
        try {
            return gdnService.searchCtnrLoadingPrint(gdnHeaderId);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }
	
	/**
	 * 获取原装柜信息列表
	 * @param gdnHeaderId
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 */
	@ApiOperation(value = "获取原装柜信息列表",notes = "获取原装柜信息列表")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @GetMapping(value = REQUEST_MODEL + "/searchCtnrLoadingPrintList")
    public <T> PagerInfo<List<CtnrLoadingPrintListResponse>> searchCtnrLoadingPrintList(
    		@ApiParam(value = "发货单ID", required = true) 
    		@RequestParam(required = true) Integer gdnHeaderId, 
    		Pager<T> pager, 
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) {
        try {
            return gdnService.searchCtnrLoadingPrintList(gdnHeaderId, pager);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }
	
	/**
	 * 编辑原装柜信息备注
	 * @param bindingResult
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 */
	@ApiOperation(value = "编辑原装柜信息备注",notes = "编辑原装柜信息备注")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @PostMapping(value = REQUEST_MODEL + "/updateGdnDtlComment")
    public Result<?> updateGdnDtlComment(
    		@RequestBody @Valid UpdateGdnDtlCommentRequest dto, 
    		BindingResult bindingResult, 
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) {
        try {
        	ValidatorUtil.validator(bindingResult);
            return gdnService.updateGdnDtlComment(dto, servletRequest);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }
	
	/**
	 * 打印余留单pdf
	 * @param gdnHeaderId
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 * @throws Exception 
	 */
	@ApiOperation(value = "打印余留单pdf",notes = "打印余留单pdf")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @GetMapping(value = REQUEST_MODEL + "/loadingRemainPrint")
    public void loadingRemainPrint(
    		@ApiParam(value = "发货单表头ID", required = true) 
    		@RequestParam(required = true) Integer gdnHeaderId, 
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) throws Exception {
        try {
            gdnService.loadingRemainPrint(gdnHeaderId, servletRequest, servletResponse);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

	/**
	 * 打印余留单pdf
	 * @param gdnHeaderId
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 * @throws Exception
	 */
	@ApiOperation(value = "打印余留单(新)",notes = "打印余留单(新)")
	@ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
	@GetMapping(value = REQUEST_MODEL + "/loadingRemainPrintNew")
	public Result loadingRemainPrintNew(
			@ApiParam(value = "发货单表头ID", required = true)
			@RequestParam(required = true) Integer gdnHeaderId,
			HttpServletRequest servletRequest,
			HttpServletResponse servletResponse) throws Exception {
		try {
			return gdnService.loadingRemainPrintNew(gdnHeaderId, servletRequest, servletResponse);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}
	
	/**
	 * 打印发货单pdf
	 * @param gdnHeaderId
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 * @throws Exception 
	 */
	@ApiOperation(value = "打印发货单pdf",notes = "打印发货单pdf")
    @ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
    @GetMapping(value = REQUEST_MODEL + "/loadingPrint")
    public void loadingPrint(
    		@ApiParam(value = "发货单表头ID", required = true) 
    		@RequestParam(required = true) Integer gdnHeaderId, 
    		HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse) throws Exception {
        try {
            gdnService.loadingPrint(gdnHeaderId, servletRequest, servletResponse);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }


	/**
	 * 打印发货单pdf
	 * excel生成到服务器，然后调用net程序预览或者打印
	 * @param gdnHeaderId
	 * @param servletRequest
	 * @param servletResponse
	 * @return
	 * @throws Exception
	 */
	@ApiOperation(value = "打印发货单(新)",notes = "打印发货单(新)")
	@ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
	@GetMapping(value = REQUEST_MODEL + "/loadingPrintNew")
	public Result loadingPrintNew(
			@ApiParam(value = "发货单表头ID", required = true)
			@RequestParam(required = true) Integer gdnHeaderId,
			HttpServletRequest servletRequest,
			HttpServletResponse servletResponse) throws Exception {
		try {
			return  gdnService.loadingPrintNew(gdnHeaderId, servletRequest, servletResponse);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	@ApiOperation(value = "下发",notes = "下发")
	@PostMapping(value = REQUEST_MODEL + "/create_picktask/{gdnHeaderId}")
	public Result<IssuePickingResponse> createPicktask(
			@ApiParam("发货单单头ID") @PathVariable(value = "gdnHeaderId") Long gdnHeaderId,
			HttpServletRequest servletRequest,
			HttpServletResponse servletResponse) throws Exception {
		try {
			Result<IssuePickingResponse> result = picktaskService.createPiacktaskJobFromGdn(gdnHeaderId, servletRequest);
			return result;
		} catch (RestStatusException e) {
			e.printStackTrace();
			servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
			throw e;
		}
	}

    @ApiOperation(value = "下发前校验",notes = "下发前校验")
    @PostMapping(value = REQUEST_MODEL + "/create_picktask_before/{gdnHeaderId}")
    public Result createPicktaskBefore(
            @ApiParam("发货单单头ID") @PathVariable(value = "gdnHeaderId") Long gdnHeaderId,
            HttpServletRequest servletRequest,
            HttpServletResponse servletResponse) throws Exception {
        try {
            Result result = picktaskService.createPicktaskBefore(gdnHeaderId, servletRequest);
            return result;
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }

	@Deprecated
	@ApiOperation(value = "测试并发",notes = "测试并发")
	@PostMapping(value = REQUEST_MODEL + "/create_picktask/test/{gdnHeaderId}")
	public String test(
			@ApiParam("发货单单头ID") @PathVariable(value = "gdnHeaderId") Integer gdnHeaderId,
			HttpServletRequest servletRequest,
			HttpServletResponse servletResponse) throws Exception {
		try {
//			try {
//			    TimeUnit.SECONDS.sleep(10);
//			} catch (InterruptedException e) {
//			    e.printStackTrace();
//			}

			String loginName = HttpSessionUtil.getLoginName(servletRequest);
			return String.valueOf(gdnHeaderId)+loginName;
		} catch (RestStatusException e) {
			e.printStackTrace();
			servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
			throw e;
		}
	}

	@ApiOperation(value = "修改装柜顺序",notes = "修改装柜顺序")
	@ApiResponses({ @ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class) })
	@GetMapping(value = REQUEST_MODEL + "/updateCtnrSeq")
	public Result<?> updateCtnrSeq(
			@ApiParam(value = "发货单表头ID") BigDecimal gdnHeaderId,
			@ApiParam(value = "发货单明细ID") BigDecimal gdnDtlId,
			@ApiParam(value = "装柜顺序") Integer ctnrSequence,
			HttpServletRequest servletRequest,
			HttpServletResponse servletResponse)  {
		try {
			return gdnService.updateCtnrSequence(gdnHeaderId, gdnDtlId, ctnrSequence);
		} catch (Exception e) {
			e.printStackTrace();
			servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
			throw e;
		}
	}


}
